package com.ruoyi.video.service.impl;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.video.domain.Video;
import com.ruoyi.video.domain.VideoFile;
import com.ruoyi.video.mapper.VideoMapper;
import com.ruoyi.video.service.IVideoFileService;
import com.ruoyi.video.service.IVideoService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;

/**
 * 番剧Service业务层处理
 *
 * @author ruoyi
 * @date 2022-02-04
 */
@Service
public class VideoServiceImpl implements IVideoService {

    @Autowired
    private VideoMapper videoMapper;

    @Autowired
    private IVideoFileService videoFileService;

    /**
     * 查询番剧
     *
     * @param id 番剧主键
     * @return 番剧
     */
    @Override
    public Video selectVideoById(String id) {
        return videoMapper.selectVideoById(id);
    }

    /**
     * 查询番剧列表
     *
     * @param video 番剧
     * @return 番剧
     */
    @Override
    public List<Video> selectVideoList(Video video) {
        return videoMapper.selectVideoList(video);
    }

    /**
     * 新增番剧
     *
     * @param video 番剧
     * @return 结果
     */
    @Override
    public int insertVideo(Video video) {
        video.setCreateTime(DateUtils.getNowDate());
        return videoMapper.insertVideo(video);
    }

    /**
     * 修改番剧
     *
     * @param video 番剧
     * @return 结果
     */
    @Override
    public int updateVideo(Video video) {
        int row = 0;
        Video video1 = selectVideoById(video.getId());
        //如果修改了视频名称则修改文件夹名
        if (!video.getName().equals(video1.getName())) {
            if (new File(FileUtils.splicingFilePath(RuoYiConfig.getVideoPath(), video1.getName())).renameTo(new File(FileUtils.splicingFilePath(RuoYiConfig.getVideoPath(), video.getName())))) {
                VideoFile videoFile = new VideoFile();
                videoFile.setVideoId(video.getId());
                List<VideoFile> videoFiles = videoFileService.selectVideoFileList(videoFile);
                videoFiles.forEach(v -> {
                    if (StringUtils.isNotEmpty(v.getFilePath()))
                        v.setFilePath(v.getFilePath().replace(video.getName(), video1.getName()));
                    if (StringUtils.isNotEmpty(v.getSubtitlePath()))
                        v.setSubtitlePath(v.getSubtitlePath().replace(video.getName(), video1.getName()));
                });
                if (CollectionUtils.isNotEmpty(videoFiles)) {
                    row += videoFileService.batchSave(videoFiles);
                }
            } else {
                return row;
            }
        }
        return row + videoMapper.updateVideo(video);
    }

    /**
     * 批量删除番剧
     *
     * @param ids 需要删除的番剧主键
     * @return 结果
     */
    @Override
    public int deleteVideoByIds(String[] ids) {
        return videoMapper.deleteVideoByIds(ids);
    }

    /**
     * 删除番剧信息
     *
     * @param id 番剧主键
     * @return 结果
     */
    @Override
    public int deleteVideoById(String id) {
        return videoMapper.deleteVideoById(id);
    }

    @Override
    public List<Video> selectVideoByIds(String[] videoIds) {
        return videoMapper.selectVideoByIds(videoIds);
    }

    @Override
    public List<Video> selectHistoryVideoList() {
        return videoMapper.selectHistoryVideoList();
    }

    @Override
    public int syncVideoFolder() {
        int row = 0;
        File file = new File(RuoYiConfig.getVideoPath());
        File[] files = file.listFiles();
        HashMap<Video, ArrayList<VideoFile>> map = new HashMap<>();
        //HashSet<String> sss3 = new HashSet<>();
        if (Objects.isNull(files)) return 0;
        for (File f : files) {
            //排除回收站和视频临时文件夹
            String absolutePath = f.getAbsolutePath();
            if (absolutePath.contains("$RECYCLE.BIN") || absolutePath.contains("videoTemporary")) continue;

            File[] videos = f.listFiles();// text/plain
            if (f.isFile() || Objects.isNull(videos)) continue;
            ArrayList<VideoFile> strings = new ArrayList<>();
            String videoId = IdUtils.fastUUID();
            int i = 0;
            for (File video : videos) {
                String videoName = video.getName();
//                if (videoName.lastIndexOf(".") != -1) {
//                    sss3.add(videoName.substring(videoName.lastIndexOf(".")));
//                }
                if (videoName.endsWith(".ass") || videoName.endsWith(".srt") || videoName.endsWith(".ssa") || videoName.endsWith(".txt")) {
                    continue;
                }
//                if (videoName.contains("迷途猫")) {
//                    System.out.println("----");
//                }
                VideoFile videoFile = new VideoFile();
                videoFile.setId(IdUtils.fastUUID());
                videoFile.setVideoId(videoId);
                videoFile.setFilePath(video.getAbsolutePath());
                videoFile.setSort(i++);
                videoFile.setVideoNumber(i + "");
                videoFile.setFileName(videoName);
                videoFile.setExtendedName(getExtendedName(videoName));
                File assFile = getSubtitleFile(video);
                if (Objects.nonNull(assFile) && assFile.exists()) {
                    videoFile.setSubtitlePath(assFile.getAbsolutePath());
                    videoFile.setSubtitleName(assFile.getName());
                    videoFile.setSubtitleExtendedName("text/plain");
                }
                strings.add(videoFile);
            }
            if (CollectionUtils.isNotEmpty(strings)) {
                Video v = new Video();
                v.setId(videoId);
                v.setName(f.getName());
                map.put(v, strings);
            }
        }
        for (Video k : map.keySet()) {
            Video v = selectVideoByName(k.getName());
            if (v != null) continue;
            row += insertVideo(k);
            row += videoFileService.batchSave(map.get(k));
        }
        //sss3.forEach(System.out::println);
        return row;
    }

    public Video selectVideoByName(String name) {
        return videoMapper.selectVideoByName(name);
    }

    public String getExtendedName(String fileName) {
        String[] a = {"mp4", "flv", "mkv", "mov"};
        String[] b = {"video/mp4", "flv-application/octet-stream", "video/x-matroska", "video/quicktime"};
        for (int i = 0; i < a.length; i++) {
            if (fileName.toLowerCase().endsWith(a[i])) return b[i];
        }
        return b[0];
    }

    public File getSubtitleFile(String filePath) {
        return getSubtitleFile(new File(filePath));
    }

    public File getSubtitleFile(File file) {
        String name = file.getAbsolutePath();
        int i = name.lastIndexOf(".");
        if (i == -1) return null;
        String substring = name.substring(0, i);
        for (String extendedName : FileUtils.SUBTITLE_EXTENDED_NAMES) {
            File file1 = new File(substring.concat(extendedName));
            if (file1.exists()) return file1;
        }
        return null;
    }

    public static void getFileChildrens(File file, Set<String> list) {
        //排除不存在的和隐藏文件
        if (!file.exists() || file.isHidden()) {
            return;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files == null || files.length == 0) return;
            for (File listFile : files) {
                getFileChildrens(listFile, list);
            }
        } else {
            String absolutePath = file.getAbsolutePath();
            //排除回收站和视频临时文件夹
            if (absolutePath.contains("$RECYCLE.BIN") || absolutePath.contains("videoTemporary")) return;
            list.add(absolutePath);
        }
    }
}
